const Excel = require('exceljs');
const { Readable } = require("stream");
const utils = require("../../utils");
const _ = require('lodash');


function getValues(values, startCol) {
  return _.map(values.slice(startCol), o => {
    if (o && o.richText) {
      return _.map(o.richText, m => m.text).join('');
    }
    if (o && o.result) {
      return o.result;
    }
    if (o && o.error) {
      return undefined;
    }
    return o;
  }).map(o => o === undefined ? '' : o);
}
async function getWorkSheet(filename, sheetIndex) {
  const wb = new Excel.Workbook();
  await wb.xlsx.readFile(filename);
  const ws = wb.worksheets[sheetIndex];
  return ws;
}

module.exports = function (file, { sheet = 0, startRow = 1, startCol = 1, hasTitle = true } = {}) {
  const stream = new Readable({ objectMode: true });
  let ws, fields, rowNo = startRow;
  getWorkSheet(file, sheet).then(_ws => {
    ws = _ws;
    if (hasTitle) {
      rowNo = startRow + 1;
      fields = getValues(ws.getRow(startRow).values, startCol);
    }
  });

  stream._read = async function () {
    !ws && await utils.until(() => ws);
    if (rowNo <= ws.actualRowCount) {
      const row = ws.getRow(rowNo);
      const values = getValues(row.values, startCol);
      stream.push(hasTitle ? _.zipObject(fields, values) : values);
    } else {
      stream.push(null);
    }
    rowNo++;
  };

  stream.on('end', () => {
    utils.debug('excelReader [end]');
  });
  
  return stream;
}